//
//  ArcVC.swift
//  swiftDemo
//
//  Created by mac on 2017/3/23.
//  Copyright © 2017年 毕小强. All rights reserved.
//

import UIKit

class ArcVC: UIViewController {
    private var reference1: Person?
    private var reference2: Person?
    private var reference3: Person?
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        
        //引用计数
        reference1 = Person(name: "John Appleseed")
        reference2 = reference1
        reference3 = reference1
        print(reference2!.name)
        print(reference3!.name)
        reference1 = nil
        reference2 = nil
        reference3 = nil
        
        //循环强引用
        var john:Person? = Person(name: "John")
        var unit4a:Apartment? = Apartment(unit: "4a")
        
        john!.aparment = unit4a
        unit4a!.person = john
        
        john = nil
        unit4a = nil
        
        var jack:Customer? = Customer(name: "Jack")
        jack!.card = CreditCard(number: 0291039482, customer: jack!)
        jack = nil
        
        var country:Country? = Country(name: "Japan", capitalCityName: "Tokyo")
        print(country!.name)
        country = nil
        
        var html:HTMLElement? = HTMLElement(name: "p", text: "这是个段落")
        let str = html!.asHTML()
        let str1 = html!.adHTML("皮皮虾","我们走")
        let str2 = html!.abHTML("黄鳝姐","我们走")
        print(str)
        print(str1)
        print(str2)
        html = nil
        // Do any additional setup after loading the view.
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

//weak弱引用解决循环引用
class Person {
    let name: String
    var aparment:Apartment?
    
    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}

class Apartment {
    let unit :String
    init(unit:String) {
        self.unit = unit
        print("\(unit)被初始化了")
    }
    weak var person : Person?
    deinit {
        print("\(unit)被释放了")
    }
}

//unowned无主引用解决循环引用
class Customer{
    let name:String
    var card :CreditCard?
    init(name:String) {
        self.name = name
    }
    deinit {
        print("\(name)被释放了")
    }
    
}
class CreditCard {
    let number:UInt64
    unowned let customer:Customer
    init(number:UInt64,customer:Customer) {
        self.number = number
        self.customer = customer
        
    }
    deinit {
        print("\(number)被释放了")
    }
}

//无主引用和隐式展开的可选属性
class Country{
    let name:String
    var capitalCity:City!
    init(name:String , capitalCityName:String) {
        self.name = name
        self.capitalCity = City(name: capitalCityName, country: self)
    }
    deinit {
        print("国家\(name)被释放了")
    }
}
class City {
    let name:String
    unowned let country:Country
    init(name:String,country:Country) {
        self.name = name
        self.country = country
    }
    deinit {
        print("城市\(name)被释放了")
    }
}

//闭包强引用 通过捕获列表解决闭包强引用
class HTMLElement {
    var name:String
    var text:String?
    
    lazy var asHTML: () -> String = {
        [unowned self] in
        if let text = self.text {
             return "<\(self.name)>\(text)</\(self.name)>"
        }else{
            return "\(self.name)/"
        }
    }
    
    lazy var adHTML: (String , String) -> String = {(index,vstringToProcess) in
        //[unowned self](index:String,vstringToProcess: String)->String in
        return "\(index)\(vstringToProcess)"
    }
    
    lazy var abHTML = {(s1:String,s2:String) -> String in
        return s1+s2
    }
    
    init(name:String,text:String? = nil) {
        self.name = name
        self.text = text
    }
    deinit {
        print("\(name)被释放了")
    }
}

